function getterFn(key, fn) {
  if (typeof fn === 'function') return fn
  let getter = fn.get
  return getter
}
const prefix = '_async_computed$'
function generateDefault(fn, pluginOptions) {
  let defaultValue = null

  if ('default' in fn) {
    defaultValue = fn.default
  } else if ('default' in pluginOptions) {
    defaultValue = pluginOptions.default
  }

  if (typeof defaultValue === 'function') {
    return defaultValue.call(this)
  } else {
    return defaultValue
  }
}
function initDataWithAsyncComputed(options, pluginOptions = {}) {
  const optionData = options.data
  const asyncComputed = options.asyncComputed || {}

  return function vueAsyncComputedInjectedDataFn(vm) {
    const data =
      (typeof optionData === 'function'
        ? optionData.call(this, vm)
        : optionData) || {}
    for (const key in asyncComputed) {
      const item = this.$options.asyncComputed[key]

      var value = generateDefault.call(this, item, pluginOptions)
      data[key] = value
    }
    return data
  }
}
function handleAsyncComputedPropetyChanges(vm, key) {
  let watcher = async (n) => {
    // console.log(n, o)
    vm[key] = await n
    console.log(vm[key])
  }
  vm.$watch(prefix + key, watcher, { immediate: true })
}
export default {
  beforeCreate() {
    const asyncComputed = this.$options.asyncComputed || {}

    if (!Object.keys(asyncComputed).length) return

    for (const key in asyncComputed) {
      const getter = getterFn(key, asyncComputed[key])
      // console.log(this.$options)
      this.$options.computed[prefix + key] = getter
    }

    this.$options.data = initDataWithAsyncComputed(this.$options)
    // console.log(this.$options.data, 151)
  },
  computed: {},
  mounted() {
    for (const key in this.$options.asyncComputed || {}) {
      const item = this.$options.asyncComputed[key],
        value = generateDefault.call(this, item, {})
      this[key] = value
    }
    for (const key in this.$options.asyncComputed || {}) {
      handleAsyncComputedPropetyChanges(this, key, {})
    }
  },
}
